package com.maiji.cloud.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.maiji.cloud.config.MyRedisConfig;
import com.maiji.cloud.entities.community.*;
import com.maiji.cloud.entities.login.*;
import com.maiji.cloud.mapper.*;
import com.maiji.cloud.microservice.UploadRecordService;
import com.maiji.cloud.microservice.UserInfoService;
import com.maiji.cloud.repository.ComMsgInfoRepository;
import com.maiji.cloud.request.*;
import com.maiji.cloud.request.community.*;
import com.maiji.cloud.request.shopingmall.DistributeIntegralReqDto;
import com.maiji.cloud.response.*;
import com.maiji.cloud.response.community.*;
import com.maiji.cloud.response.login.LocationResDto;
import com.maiji.cloud.response.login.UploadImageResData;
import com.maiji.cloud.response.login.UserInfoResData;
import com.maiji.cloud.response.shopingmall.FinancialDetailsResData;
import com.maiji.cloud.scheduled.MaijiAsyncService;
import com.maiji.cloud.service.*;
import com.maiji.cloud.utils.*;
import com.sun.istack.NotNull;
import org.apache.commons.lang.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.jetty.util.StringUtil;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.QueryStringQueryBuilder;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import java.text.MessageFormat;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Transactional
public class CommunityServiceImpl extends ServiceImpl<ComMsgInfoMapper,ComMsgInfo> implements CommunityService {
	private static final Logger logger = LoggerFactory.getLogger(CommunityServiceImpl.class);
	
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private UserInfoService userInfoService;
    @Autowired
    private UploadRecordService uploadRecordService;
    @Autowired
    private ComPraiseService praiseService;
    @Autowired
    private ComMsgCollectService msgCollectService;
    @Autowired
    @Lazy
    private AsyncService asyncService;
    @Autowired
    private ComMsgInfoMapper comMsgInfoMapper;
    @Autowired
    private ComUserRelationMapper userRelationMapper;
    @Autowired
    private ComLocationInfoMapper locationInfoMapper;
    @Autowired
    private ComAtWhoMapper atWhoMapper;
    @Autowired
    private ComActService actService;
    @Autowired
    private ComMsgInfoRepository msgInfoRepository;
    @Autowired
    private ComMsgTransmitMapper msgTransmitMapper;
    @Autowired
    private IntegralService integralService;
    @Autowired
    private MaijiAsyncService maijiAsyncService;
    @Value("${x-oss-process-imageResize}")
    private String imageResize;
    @Value("${realmName}")
    private String realmName;

    @Autowired
    private ComMidActMapper comMidActMapper;

    @Autowired
    private ComMidLabelService comMidLabelService;

    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 发送动态
     * @param reqDto
     * @param token
     * @return
     */
    @Override
    public BaseOutPutDto<ComRecsOutputDto> publishCom(BaseInputDto<ComPubComInputDto> reqDto, String token) {

        AppUser appUser = RedisUtil.getAppUserByRedis(redisTemplate, MyRedisConfig.REDISDATABASENO, token, userInfoService);
        String userId = appUser.getUuId();

        BaseOutPutDto<ComRecsOutputDto> baseOut = new BaseOutPutDto();
        ComPubComInputDto comInputDto = reqDto.getData();

        if(comInputDto.getType() == 0 && StringUtils.isBlank(comInputDto.getContent())){
            baseOut.setStatus(Status.ERROR);
            baseOut.setMessage("内容不可以为空");
            return baseOut;
        }

        if(!WXUtil.examineText(comInputDto.getContent())){
            baseOut.setStatus(Status.NON_COMPLIANCE);
            return baseOut;
        }

        try {


            ComMsgInfo msgInfo = new ComMsgInfo();
            if(BooleanUtils.isTrue(comInputDto.getShowLocation()) == true && comInputDto.getLocation() != null){
                String locationId = UUID_MD5.getUUID();
                ComLocationInfo locationInfo = new ComLocationInfo();
                BeanUtils.copyProperties(comInputDto.getLocation(),locationInfo);
                locationInfo.setUuId(locationId);
                msgInfo.setLocationId(locationId);

                locationInfoMapper.insert(locationInfo);
            }
            BeanUtils.copyProperties(comInputDto,msgInfo);
            msgInfo.setMsgId(UUID_MD5.getUUID())
                    .setShowLocation(comInputDto.getShowLocation())
                    .setUserId(userId).
                    setPublishTime(TimeUtil.getCurDateStamp());
            asyncService.asycSaveMsgInfo(msgInfo);

            ArrayList<SaveURBelongIdReqDto> saveURBelongIds = new ArrayList<>();
            if(comInputDto.getType() == 1){

                for (String imageId:comInputDto.getImageIds()) {
                    SaveURBelongIdReqDto saveURBelongIdReqDto = new SaveURBelongIdReqDto();
                    saveURBelongIdReqDto.setBelongId(msgInfo.getMsgId())
                            .setImageId(imageId);
                    saveURBelongIds.add(saveURBelongIdReqDto);

                    BaseInputDto<ArrayList<SaveURBelongIdReqDto>> uploadInputDto = new BaseInputDto<>();
                    uploadInputDto.setData(saveURBelongIds);
                    uploadRecordService.saveBelongId(uploadInputDto);
                }

            }else if(comInputDto.getType() == 2){
                SaveURBelongIdReqDto saveURBelongIdReqDto = new SaveURBelongIdReqDto();
                saveURBelongIdReqDto.setBelongId(msgInfo.getMsgId())
                        .setImageId(comInputDto.getVideoId());
                saveURBelongIds.add(saveURBelongIdReqDto);

                BaseInputDto<ArrayList<SaveURBelongIdReqDto>> uploadInputDto = new BaseInputDto<>();
                uploadInputDto.setData(saveURBelongIds);
                uploadRecordService.saveBelongId(uploadInputDto);
            }else if(comInputDto.getType() == 3){

                List<UploadRecord> uploadRecords = Lists.newArrayList();
                msgInfo.setContent( DetailTextUtil.dealDetailText(MaijiOSS.OSSARTICLEBUKET,msgInfo.getMsgId(),msgInfo.getContent(),uploadRecords));
                if (uploadRecords.size() > 0 && ! uploadRecordService.insertBatchUploadRecord(uploadRecords)){
                    baseOut.setStatus(Status.ERROR);
                    return baseOut;
                }

            }

            insert(msgInfo);
            if (comInputDto.getImageIds() != null && comInputDto.getImageIds().length > 0)
                maijiAsyncService.examineImgAsync(msgInfo.getMsgId());
            String regex = "#(.*?)#";
            ArrayList<String> actStrs = new ArrayList();
            if(msgInfo.getContent() != null){
                List<String> contentActs = StringUitl.subsStringWithRegex(msgInfo.getContent(),regex);
                if(contentActs != null){
                    actStrs.addAll(contentActs);
                }
            }
            if(msgInfo.getTitle() != null){
                List<String> titleActs =  StringUitl.subsStringWithRegex(msgInfo.getTitle(),regex);
                if(titleActs != null){
                    actStrs.addAll(titleActs);
                }
            }
            List<ComActivityDto> searchs = new ArrayList();
            if(actStrs.size()>0){
                ArrayList<ComActMidInputDto> middleActivities = new ArrayList<>();
                for (String str:actStrs
                ) {
                    ComActMidInputDto middleActivity = new ComActMidInputDto();
                    middleActivity.setActName(str);
                    middleActivity.setMsgId(msgInfo.getMsgId());
                    middleActivities.add(middleActivity);

                    ComActivityDto searchInputDto = new ComActivityDto();
                    searchInputDto.setActName(str);
                    searchs.add(searchInputDto);
                }
                BaseInputDto<List<ComActivityDto>> actsInput = new BaseInputDto<>();
                actsInput.setData(searchs);
                actService.addActs(actsInput);
                BaseInputDto<List<ComActMidInputDto>> actmidInput = new BaseInputDto<>();
                actmidInput.setData(middleActivities);
                actService.addMsgActs(actmidInput);
            }

            if(comInputDto.getAtList() != null && comInputDto.getAtList().length>0){
                List<ComAtWhoInputDto> atWhoInputDtos = new ArrayList<>();
                for (String atStr:comInputDto.getAtList()){
                    ComAtWhoInputDto atWhoInputDto = new ComAtWhoInputDto();
                    atWhoInputDto.setSourceId(msgInfo.getMsgId());
                    atWhoInputDto.setSourceUserId(userId);
                    atWhoInputDto.setAtUserId(atStr);
                    atWhoInputDtos.add(atWhoInputDto);
                }
                addAtList(new BaseInputDto(atWhoInputDtos));
                createAtMessages(msgInfo,comInputDto.getAtList(),userId);
            }

            ComRecsOutputDto recsOutputDto = reloadMsgInfo(msgInfo,userId);

            {
                //用户每天第一次发布 有积分
                EntityWrapper<ComMsgInfo> entityWrapper = new EntityWrapper<>();
                ComMsgInfo countMsgInfo = new ComMsgInfo();
                countMsgInfo.setUserId(userId);
                entityWrapper.setEntity(countMsgInfo);
                Long startTime = TimeUtil.getZeroTime(new Date()).getTime();
                Long endTime = TimeUtil.getCurDateStamp();
                entityWrapper.where(MessageFormat.format("publish_time >= {0} and {1} >= publish_time",startTime.toString() ,endTime.toString()));
                if(comMsgInfoMapper.selectCount(entityWrapper) == 1){
                    DistributeIntegralReqDto distributeIntegralReqDto = new DistributeIntegralReqDto();
                    DistributeIntegralReqDto.DistributeIntegralReqData distributeIntegralReqData = distributeIntegralReqDto.dataInstance();
                    distributeIntegralReqData.setRemark(FlowTypeEnum.PUBLISH);
                    distributeIntegralReqData.setRelevantId(msgInfo.getMsgId());
                    distributeIntegralReqDto.setData(distributeIntegralReqData);
                    FinancialDetailsResData financialDetails = integralService.distributeIntegralByRemarkInt(distributeIntegralReqDto,token).getData();
                    recsOutputDto.setFinancial(financialDetails);

                }
            }

            baseOut.setData(recsOutputDto);
            baseOut.setStatus(Status.SUCCESS);
            baseOut.setMessage("发布成功");

            return baseOut;
        }catch (Exception error){

            baseOut.setMessage(error.getMessage());
            baseOut.setStatus(Status.ERROR);
            return baseOut;
        }

    }

    /**
     * 动态详细
     * @param maijiToken
     * @return
     */
    public BaseOutPutDto<ComDetailOutputDto> detailMsg(@RequestBody BaseInputDto<IdInputDto> inputDto, @RequestHeader("maijiToken")String maijiToken){

        String userId = "";
        if(!StringUtil.isBlank(maijiToken)){
            AppUser appUser = RedisUtil.getAppUserByRedis(redisTemplate, MyRedisConfig.REDISDATABASENO, maijiToken, userInfoService);
            if(appUser != null){
                userId = appUser.getUuId();
            }
        }


        BaseOutPutDto<ComDetailOutputDto> baseOutPutDto = new BaseOutPutDto<>();
        try{
            if(inputDto.getData() != null && inputDto.getData().getId() != null){
                ComDetailOutputDto detailOutputDto = new ComDetailOutputDto();
                ComMsgInfo msgInfo = comMsgInfoMapper.detail(inputDto.getData().getId(),userId);

                ComRecsOutputDto recsOutputDto = reloadMsgInfo(msgInfo,userId);
                detailOutputDto.setDetailMsg(recsOutputDto);
                BaseInputDto<IdInputDto> msgInput = new BaseInputDto<>(new IdInputDto(msgInfo.getMsgId()));
                ReqMetaData metaData = new ReqMetaData();
                metaData.setSize(21);
                msgInput.setMetaData(metaData);
                BaseOutPutDto<List<UserInfoResData>> praisers = praiseService.praiseList(msgInput);
                if(praisers.getData() != null){
                    detailOutputDto.setPraisers(praisers.getData());
                }

//                BaseOutPutDto<List<ComCommentOutputDto>> comments = commentService.commentList(msgInput,maijiToken);
////                if(comments.getData() != null){
////                    detailOutputDto.setComments(comments.getData());
////                }

                baseOutPutDto.setStatus(Status.SUCCESS);
                baseOutPutDto.setData(detailOutputDto);
            }else {
                baseOutPutDto.setStatus(Status.PARAMETERERROR);
            }


            return baseOutPutDto;
        }catch (Exception exc){
            baseOutPutDto.setStatus(Status.ERROR);
            baseOutPutDto.setMessage(exc.getMessage());
            return baseOutPutDto;
        }
    }

    /**
     * 加载msginfo实体类信息
     * @param comMsgInfos
     * @returnfindListByMsgIds
     */
    public BaseOutPutDto<List<ComRecsOutputDto>> reloadMsgInfos(@NotNull List<ComMsgInfo> comMsgInfos,String userId){
        List<ComRecsOutputDto> recsOutputDtos = new ArrayList<ComRecsOutputDto>();
        for (ComMsgInfo msginfo:comMsgInfos) {
            if(((msginfo.getDelete() != null && msginfo.getDelete() == 3) || (msginfo.getIsolation() != null && msginfo.getIsolation() == true)) && msginfo.getUserId().equals(userId) == false){
                continue;
            }
            if(msginfo.getDelete() != null && msginfo.getDelete() != 0){
                continue;
            }
            recsOutputDtos.add(reloadMsgInfo(msginfo,userId));
        }
        BaseOutPutDto<List<ComRecsOutputDto>> outPutDto = new BaseOutPutDto<List<ComRecsOutputDto>>();
        outPutDto.setData(recsOutputDtos);
        outPutDto.setStatus(Status.SUCCESS);
        return outPutDto;
    }

    /**
     * 加载msginfo实体类信息
     * @param comMsgInfos
     * @returnfindListByMsgIds
     */
    public BaseOutPutDto<List<ComRecsOutputDto>> reloadMsgInfosNoDelete(@NotNull List<ComMsgInfo> comMsgInfos,String userId){
        List<ComRecsOutputDto> recsOutputDtos = new ArrayList<ComRecsOutputDto>();
        for (ComMsgInfo msginfo:comMsgInfos) {
            recsOutputDtos.add(reloadMsgInfo(msginfo,userId));
        }
        BaseOutPutDto<List<ComRecsOutputDto>> outPutDto = new BaseOutPutDto<List<ComRecsOutputDto>>();
        outPutDto.setData(recsOutputDtos);
        outPutDto.setStatus(Status.SUCCESS);
        return outPutDto;
    }


    private ComRecsOutputDto reloadMsgInfo(@NotNull ComMsgInfo msginfo,@NotNull String userId){
        BaseInputDto<IdInputDto> idInput = new BaseInputDto();
        idInput.setData(new IdInputDto().setId(msginfo.getUserId()));
        ComRecsOutputDto recsOutputDto = new ComRecsOutputDto();
        UserInfoResData userInfoResData = new UserInfoResData();

//          是否是粉丝关注人关系
        if(msginfo.getUserRelations() != null){

            if(msginfo.getUserRelations().size() > 0&&msginfo.getUserRelations().get(0).getFollowerId() != null && msginfo.getUserRelations().get(0).getFocuserId() != null){
                userInfoResData.setIsFollow(true);
            }else{
                userInfoResData.setIsFollow(false);
            }
        }


        if(msginfo.getUserInfo() != null){
            BeanUtils.copyProperties(msginfo.getUserInfo(), userInfoResData);
            if(msginfo.getUserId().equals(userId)){
                userInfoResData.setIsUse(1);
            }
            recsOutputDto.setUser(userInfoResData);
        }

//            设置发送动态的用户信息

//            填充参数
        ComMsgBaseOutputDto msgBase = new ComMsgBaseOutputDto();
        BeanUtils.copyProperties(msginfo,msgBase);

        if(msginfo.getUserId() != null && msginfo.getUserId().equals(userId)){
            msgBase.setIsOfSelf(true);
        }

        if(msginfo.getUploadRecords() != null){

            List<UploadImageResData> fileResDtos = new ArrayList<>();
//            获取动态视频或者图片
            for (UploadRecord uploadRecord:msginfo.getUploadRecords()
            ) {
                UploadImageResData fileResDto = new UploadImageResData();
                BeanUtils.copyProperties(uploadRecord, fileResDto);
                fileResDto.setSmallUrl(fileResDto.getUrl() + "?" + imageResize);
                fileResDtos.add(fileResDto);
            }
            msgBase.setFiles(fileResDtos);
        }

        //判断是否可以转发得积分
        if((msginfo.getIsIntegral() != null && msginfo.getIsIntegral() == 1)){
            msgBase.setCanGetIntegral(true);
        }
//            访问用户跟动态是否有点赞关系
        if(msginfo.getPraise() != null && msginfo.getPraise().getPraiserId() != null && msginfo.getPraise().getBelongId() != null){
            msgBase.setIsPraise(true);
        }
        if(msginfo.getCollect() != null && msginfo.getCollect().getBelongId() != null && msginfo.getCollect().getCollecterId() != null){
            msgBase.setIsCollect(true);
        }
        if(msginfo.getLocationInfo() != null){
            LocationResDto locationResDto = new LocationResDto();
            BeanUtils.copyProperties(msginfo.getLocationInfo(),locationResDto);
            msgBase.setLocation(locationResDto);
        }
        if(msginfo.getComments() != null){
            List<ComCommentOutputDto> commentOutputDtos = new ArrayList<>();
            for (ComComment comment :msginfo.getComments()){
                ComCommentOutputDto comCommentOutputDto = new ComCommentOutputDto();
                BeanUtils.copyProperties(comment,comCommentOutputDto);
                if(comment.getTargetUserId().equals(userId)){
                    comCommentOutputDto.setIsOfSelf(true);
                }

                commentOutputDtos.add(comCommentOutputDto);
            }
            msgBase.setComments(commentOutputDtos);
        }

        //加载at用户列表
        if(msginfo.getAtUserIds() != null){
            ArrayList<String> atUserIds = new ArrayList();
            for (ComAtWho at : msginfo.getAtUserIds()){
                atUserIds.add(at.getAtUserId());
            }
            msgBase.setAtUserIds(atUserIds);
        }

        if(msginfo.getLabels() != null){
            ArrayList<ComLabelOutputDto> labelOutputDtos = new ArrayList<>();
            for(ComMiddleLabel label : msginfo.getLabels()){
                ComLabelOutputDto labelOutputDto = new ComLabelOutputDto();
                labelOutputDto.setLabelName(ComLabelEnum.getLabel(label.getLabelId()).getMessage());
                labelOutputDto.setBgColor(ComLabelEnum.getLabel(label.getLabelId()).getBgColor());
                labelOutputDtos.add(labelOutputDto);
            }
            msgBase.setLabels(labelOutputDtos);
        }

        recsOutputDto.setMsg(msgBase);
        recsOutputDto.setMsgId(msgBase.getMsgId());
        recsOutputDto.setUserId(msgBase.getUserId());

        return recsOutputDto;
    }

    /**
     * 案例列表
     * @param inputDto
     * @param maijiToken
     * @return
     */
    public BaseOutPutDto<List<ComRecsOutputDto>> caseList(BaseInputDto<ComRecsInputDto> inputDto,String maijiToken){

        String userId = "";
        if(!StringUtil.isBlank(maijiToken)){
            AppUser appUser = RedisUtil.getAppUserByRedis(redisTemplate, MyRedisConfig.REDISDATABASENO, maijiToken, userInfoService);
            if(appUser != null){
                userId = appUser.getUuId();
            }
        }
//        ArrayList<ComMsgInfo> comMsgInfos = new ArrayList();
//
//        if(inputDto.getData().getPublishTime() == null || inputDto.getData().getPublishTime() == 0){
//            List<ComMsgInfo> topList = comMsgInfoMapper.topList(userId);
//            if(topList != null && topList.size() > 0){
//                comMsgInfos.addAll(topList);
//            }
//        }
//
//        ComRecsInputDto recsInputDto = inputDto.getData();
//        ReqMetaData metaData = inputDto.getMetaData();
//        List<ComMsgInfo> caseList = comMsgInfoMapper.caseList(userId,recsInputDto.getPublishTime(),0,metaData.getSize());
//        if(caseList != null){
//            comMsgInfos.addAll(caseList);
//        }
//
//        return this.reloadMsgInfos(comMsgInfos,userId);
        return findMsgInfosByLabelId(inputDto,ComLabelEnum.ComLabelEnum_Ce.getValue(),userId);
    }


    /**
     * 推荐列表 priority 优先级>=1
     * @param inputDto
     * @param maijiToken
     * @return
     */
    @Override
    public BaseOutPutDto<List<ComRecsOutputDto>> recommends(BaseInputDto<ComRecsInputDto> inputDto,String maijiToken){

        return this.loadMsgsList(inputDto,maijiToken,1);
    }


    public BaseOutPutDto<List<ComRecsOutputDto>> caseRecommends(BaseInputDto<ComRecsInputDto> inputDto,String maijiToken){
        String userId = "";
        if(!StringUtil.isBlank(maijiToken)){
            AppUser appUser = RedisUtil.getAppUserByRedis(redisTemplate, MyRedisConfig.REDISDATABASENO, maijiToken, userInfoService);
            if(appUser != null){
                userId = appUser.getUuId();
            }
        }
        return this.findMsgInfosByLabelId(inputDto,ComLabelEnum.ComLabelEnum_Cs.getValue(),userId);
    }

    /**
     * 普通列表  priority 优先级>=0
     * @param inputDto
     * @param maijiToken
     * @return
     */
    @Override
    public BaseOutPutDto<List<ComRecsOutputDto>> commonMsgs(BaseInputDto<ComRecsInputDto> inputDto,String maijiToken){

        return this.loadMsgsList(inputDto,maijiToken,0);
    }

    private BaseOutPutDto<List<ComRecsOutputDto>> loadMsgsList(BaseInputDto<ComRecsInputDto> inputDto,String maijiToken, Integer priority){

        String userId = "";
        if(!StringUtil.isBlank(maijiToken)){
            AppUser appUser = RedisUtil.getAppUserByRedis(redisTemplate, MyRedisConfig.REDISDATABASENO, maijiToken, userInfoService);
            if(appUser != null){
                userId = appUser.getUuId();
            }
        }


//        获取主表ComMsgInfo信息
        ComRecsInputDto recsInputDto = inputDto.getData();
        ReqMetaData metaData = inputDto.getMetaData();
        List<ComMsgInfo> comMsgInfos = comMsgInfoMapper.recommends(userId,recsInputDto.getPublishTime(),0 ,metaData.getSize(),priority,false,recsInputDto.getActName());

        return this.reloadMsgInfos(comMsgInfos,userId);

    }

    /**
     * 社区通用列表查询
     * @param inputDto
     * @param maijiToken
     *
     * @return
     */
    public BaseOutPutDto<List<ComRecsOutputDto>> msgList(BaseInputDto<ComRecsInputDto> inputDto,String maijiToken){

        String userId = "";
        if(!StringUtil.isBlank(maijiToken)){
            AppUser appUser = RedisUtil.getAppUserByRedis(redisTemplate, MyRedisConfig.REDISDATABASENO, maijiToken, userInfoService);
            if(appUser != null){
                userId = appUser.getUuId();
            }
        }

//        获取主表ComMsgInfo信息
        ComRecsInputDto recsInputDto = inputDto.getData();
        ReqMetaData metaData = inputDto.getMetaData();
        Boolean isCur = true;
        if(inputDto.getData().getPriority() == -1){
            isCur = false;
        }
        List<ComMsgInfo> comMsgInfos = comMsgInfoMapper.recommends(userId,inputDto.getData().getPublishTime(),(metaData.getPage() - 1) * metaData.getSize() ,metaData.getSize(),recsInputDto.getPriority(),isCur,recsInputDto.getActName());
        BaseOutPutDto outPutDto = this.reloadMsgInfos(comMsgInfos,userId);
        Integer count = comMsgInfoMapper.normalCount(userId,recsInputDto.getPublishTime(),recsInputDto.getPriority(),isCur,recsInputDto.getActName());
        outPutDto.setResMetaData(new ResMetaData(inputDto.getMetaData().getPage(),inputDto.getMetaData().getSize(),count.longValue()));

        return outPutDto;

    }

    /**
     * 发现 、 精选 、 积分通用接口
     * @param inputDto
     * @param maijiToken
     * @return
     */
    public BaseOutPutDto<List<ComRecsOutputDto>> unionMsgList(BaseInputDto<ComRecsInputDto> inputDto,String maijiToken){
        switch (inputDto.getData().getType()){
            case 0 :
                return commonMsgs(inputDto,maijiToken);
            case 1:
                return caseRecommends(inputDto,maijiToken);
            case 2:
                return integralList(inputDto,maijiToken);
            default:
                BaseOutPutDto outPutDto = new BaseOutPutDto();
                outPutDto.setStatus(Status.PARAMETERERROR);
                return outPutDto;
        }
    }

    /**
     * 关注人动态列表
     * @param inputDto
     * @param maijiToken
     * @return
     */
    @Override
    public BaseOutPutDto<List<ComRecsOutputDto>> focusersBlogList(@RequestBody BaseInputDto<ComRecsInputDto> inputDto, @RequestHeader("maijiToken")String maijiToken){

//        获取访问用户ID
        AppUser appUser = RedisUtil.getAppUserByRedis(redisTemplate, MyRedisConfig.REDISDATABASENO, maijiToken, userInfoService);
        String userId = appUser.getUuId();

//        获取主表ComMsgInfo信息
        ComRecsInputDto recsInputDto = inputDto.getData();
        ReqMetaData metaData = inputDto.getMetaData();
        List<ComMsgInfo> comMsgInfos = comMsgInfoMapper.focuserBlogList(userId,recsInputDto.getPublishTime(),0,metaData.getSize());


        return reloadMsgInfos(comMsgInfos,userId);
    }

    /**
     * 我的动态列表
     * @param inputDto
     * @param maijiToken
     * @return
     */
    public BaseOutPutDto<List<ComRecsOutputDto>> mineBlogList(@RequestBody BaseInputDto inputDto,String maijiToken){

//        获取访问用户ID
        AppUser appUser = RedisUtil.getAppUserByRedis(redisTemplate, MyRedisConfig.REDISDATABASENO, maijiToken, userInfoService);
        String userId = appUser.getUuId();
        IdInputDto idInputDto = new IdInputDto();
        idInputDto.setId(userId);
        BaseInputDto<IdInputDto> inputDto2 = new BaseInputDto();
        inputDto2.setData(idInputDto);
        inputDto2.setMetaData(inputDto.getMetaData());
        return userBlogList(inputDto2,maijiToken);

    }

    /**
     * 用户动态列表
     * @param inputDto
     * @return
     */
    public BaseOutPutDto<List<ComRecsOutputDto>> userBlogList(@RequestBody BaseInputDto<IdInputDto> inputDto,String maijiToken){

//        获取访问用户ID
        AppUser appUser = RedisUtil.getAppUserByRedis(redisTemplate, MyRedisConfig.REDISDATABASENO, maijiToken, userInfoService);
        String userId = appUser.getUuId();

        IdInputDto idInputDto = inputDto.getData();
        ReqMetaData metaData = inputDto.getMetaData();
        List<ComMsgInfo> comMsgInfos = comMsgInfoMapper.findListByPublisherId(idInputDto.getId(),userId,0,(metaData.getPage() - 1) * metaData.getSize(),metaData.getSize());
        return reloadMsgInfos(comMsgInfos,userId);
    }

    /**
     * 用户被推荐过的动态列表 priority 优先级>=1
     * @param inputDto
     * @param maijiToken
     * @return
     */
    public BaseOutPutDto<List<ComRecsOutputDto>> userHotList(@RequestBody BaseInputDto<IdInputDto> inputDto,String maijiToken){
//        获取访问用户ID
        AppUser appUser = RedisUtil.getAppUserByRedis(redisTemplate, MyRedisConfig.REDISDATABASENO, maijiToken, userInfoService);
        String userId = appUser.getUuId();

        IdInputDto idInputDto = inputDto.getData();
        ReqMetaData metaData = inputDto.getMetaData();
        List<ComMsgInfo> comMsgInfos = comMsgInfoMapper.findListByPublisherId(idInputDto.getId(),userId,1,(metaData.getPage() - 1) * metaData.getSize(),metaData.getSize());
        return reloadMsgInfos(comMsgInfos,userId);
    }

    /**
     * 用户社区收藏列表
     * @param inputDto
     * @param maijiToken
     * @return
     */
    public BaseOutPutDto<List<ComRecsOutputDto>> userCollectList(@RequestBody BaseInputDto inputDto,String maijiToken){
        try {

//        获取访问用户ID
            AppUser appUser = RedisUtil.getAppUserByRedis(redisTemplate, MyRedisConfig.REDISDATABASENO, maijiToken, userInfoService);
            String userId = appUser.getUuId();
            ReqMetaData metaData = inputDto.getMetaData();
            List<String> belongIds = msgCollectService.getUserCollectIds(userId,metaData.getPage(),metaData.getSize());
            List<ComMsgInfo> comMsgInfos = new ArrayList();
            if(belongIds != null && belongIds.size()>0){
                comMsgInfos = comMsgInfoMapper.findListByMsgIds(belongIds,userId);
            }
            return reloadMsgInfos(comMsgInfos,userId);
        }catch (Exception exc){
            BaseOutPutDto outPutDto = new BaseOutPutDto();
            outPutDto.setStatus(Status.ERROR);
            outPutDto.setMessage(exc.getMessage());
            return outPutDto;
        }
    }

    /**
     * 社区置顶列表
     * @param inputDto
     * @param maijiToken
     * @return
     */
    public BaseOutPutDto<List<ComRecsOutputDto>> topList(@RequestBody BaseInputDto inputDto,String maijiToken){

        try {
//        获取访问用户ID
            String userId = "";
            if(!StringUtil.isBlank(maijiToken)){
                AppUser appUser = RedisUtil.getAppUserByRedis(redisTemplate, MyRedisConfig.REDISDATABASENO, maijiToken, userInfoService);
                if(appUser != null){
                    userId = appUser.getUuId();
                }
            }
            List<ComMsgInfo> comMsgInfos = comMsgInfoMapper.topList(userId);
            return reloadMsgInfos(comMsgInfos,userId);
        }catch (Exception exc){
            BaseOutPutDto outPutDto = new BaseOutPutDto();
            outPutDto.setStatus(Status.ERROR);
            outPutDto.setMessage(exc.getMessage());
            return outPutDto;
        }

    }

    /**
     * 可转发得积分列表
     * @param inputDto
     * @param maijiToken
     * @return
     */
    public BaseOutPutDto<List<ComRecsOutputDto>> integralList(@RequestBody BaseInputDto<ComRecsInputDto> inputDto,String maijiToken){

        String userId = "";
        if(!StringUtil.isBlank(maijiToken)){
            AppUser appUser = RedisUtil.getAppUserByRedis(redisTemplate, MyRedisConfig.REDISDATABASENO, maijiToken, userInfoService);
            if(appUser != null){
                userId = appUser.getUuId();
            }
        }
        ArrayList<ComMsgInfo> comMsgInfos = new ArrayList();

        ComRecsInputDto recsInputDto = inputDto.getData();
        ReqMetaData metaData = inputDto.getMetaData();
        List<ComMsgInfo> caseList = comMsgInfoMapper.integralList(userId,recsInputDto.getPublishTime(),0,metaData.getSize());
        if(caseList != null){
            ComMsgTransmitRule rule = findMsgTransmitRule().getData();
            Integer restartDay = 1;

            if (rule != null) {
                if (rule.getDefaultRestartDay() != null) {
                    restartDay = rule.getDefaultRestartDay();
                }
            }

            for (ComMsgInfo msginfo:caseList
            ) {


                if (msginfo.getRestartDay() != null) {
                    restartDay = msginfo.getRestartDay();
                }

                if (checkTraIntRestartDay(msginfo.getMsgId(), userId, restartDay)) {
                    comMsgInfos.add(msginfo);
                }else{

                }
            }
        }

        return this.reloadMsgInfos(comMsgInfos,userId);
    }

    /**
     * 分享成功调用
     * @param inputDto
     * @param maijiToken
     * @return
     */
    public BaseOutPutDto<FinancialDetailsResData> shareSuc(@RequestBody BaseInputDto<IdInputDto> inputDto, @RequestHeader("maijiToken")String maijiToken){

        BaseOutPutDto<FinancialDetailsResData> outPutDto = new BaseOutPutDto<>();

        try{
            AppUser appUser = RedisUtil.getAppUserByRedis(redisTemplate, MyRedisConfig.REDISDATABASENO, maijiToken, userInfoService);
            String userId = appUser.getUuId();

            ComMsgInfo comMsgInfo = comMsgInfoMapper.selectById(inputDto.getData().getId());
            if(comMsgInfo != null){
                comMsgInfo.setTransmit_count(comMsgInfo.getTransmit_count() +1);
            }
            comMsgInfoMapper.updateById(comMsgInfo);

            ComMsgTransmit msgTransmit = new ComMsgTransmit();
            msgTransmit.setSourceUserId(userId);
            msgTransmit.setBelongId(inputDto.getData().getId());

            msgTransmit.setTransmitId(UUID_MD5.getUUID());
            msgTransmit.setTransmitTime(TimeUtil.getCurDateStamp());


            if(comMsgInfo.getIsIntegral() == 1){
                //判断是否符合积分转发的等级要求

                Integer integer = 50;
                Integer restartDay = 1;
                Integer maxTransmitNum = 1;

                ComMsgTransmitRule rule = findMsgTransmitRule().getData();
                if(rule != null){
                    if(rule.getDefaultIntegral() != null){
                        integer = rule.getDefaultIntegral();
                    }
                    if(rule.getMaxTransmitNum() != null){
                        maxTransmitNum = rule.getMaxTransmitNum();
                    }
                    if(rule.getDefaultRestartDay() != null){
                        restartDay = rule.getDefaultRestartDay();
                    }
                }

                if(comMsgInfo.getIntegral() != null){
                    integer = comMsgInfo.getIntegral();
                }
                if(comMsgInfo.getRestartDay() != null){
                    restartDay = comMsgInfo.getRestartDay();
                }

                if(checkUserTraIntNum(userId,maxTransmitNum)){
                    //判断用户今天转发得积分数量是否超过规定
                    if(checkTraIntRestartDay(comMsgInfo.getMsgId(),userId,restartDay)){
                        //判断用户转发此条动态周期是否重置
                        {
                            DistributeIntegralReqDto distributeIntegralReqDto = new DistributeIntegralReqDto();
                            DistributeIntegralReqDto.DistributeIntegralReqData distributeIntegralReqData = distributeIntegralReqDto.dataInstance();
                            distributeIntegralReqData.setRemark(FlowTypeEnum.RETRANSMISSION);
                            distributeIntegralReqData.setIntegral(integer);
                            distributeIntegralReqData.setRelevantId(msgTransmit.getTransmitId());
                            distributeIntegralReqDto.setData(distributeIntegralReqData);
                            FinancialDetailsResData financialDetails = integralService.distributeIntegralByRemarkInt(distributeIntegralReqDto,maijiToken).getData();
                            outPutDto.setData(financialDetails);
                            msgTransmit.setIsIntegral(1);
                            outPutDto.setStatus(Status.SUCCESS);
                        }
                    }else {
                        outPutDto.setStatus(Status.SUCCESS);
                    }
                }else{
                    outPutDto.setStatus(Status.SUCCESS);
                    outPutDto.setMessage("今日转发得积分已超过次数");
                }

            }
            msgTransmitMapper.insert(msgTransmit);

            return outPutDto;
        }catch (Exception exc){
            outPutDto.setStatus(Status.ERROR);
            outPutDto.setMessage(exc.getMessage());
            return outPutDto;
        }

    }

    /**
     * 搜索动态
     * @param inputDto
     * @param maijiToken
     * @return
     */
    public BaseOutPutDto<List<ComRecsOutputDto>> searchMsg(@RequestBody BaseInputDto<ComSearchInputDto> inputDto, @RequestHeader("maijiToken")String maijiToken){

        try{

            AppUser appUser = RedisUtil.getAppUserByRedis(redisTemplate, MyRedisConfig.REDISDATABASENO, maijiToken, userInfoService);
            String userId = appUser.getUuId();

            ComSearchInputDto searchInputDto = inputDto.getData();
            ReqMetaData metaData = inputDto.getMetaData();
            PageRequest pageable = new PageRequest(metaData.getPage()-1,metaData.getSize());




            QueryStringQueryBuilder builder = new QueryStringQueryBuilder(searchInputDto.getText());


            BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery().must(builder);


            if(!StringUtil.isBlank(inputDto.getData().getUserId())){

                TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("userId",inputDto.getData().getUserId());
                queryBuilder.must(termQueryBuilder);
            }
            SortBuilder sortBuilder = SortBuilders.fieldSort("publishTime").order(SortOrder.DESC);
            SearchQuery searchQuery = new NativeSearchQueryBuilder()
                    .withPageable(pageable)
                    .withQuery(queryBuilder)
                    .withSort(sortBuilder)
                    .build();
            Page<ComMsgInfo> msgInfos = msgInfoRepository.search(searchQuery);

            List<String> msgIds = new ArrayList();
            for (ComMsgInfo msginfo: msgInfos.getContent()
            ) {
                msgIds.add(msginfo.getMsgId());
            }
            List<ComMsgInfo> comMsgInfos = new ArrayList<>();
            if(msgIds.size()>0){
                comMsgInfos = comMsgInfoMapper.findListByMsgIds(msgIds,userId);
            }

            return reloadMsgInfos(comMsgInfos,userId);
        }catch(Exception exceptio){
            BaseOutPutDto<List<ComRecsOutputDto>> baseOutPutDto = new BaseOutPutDto();
            baseOutPutDto.setStatus(Status.ERROR);
            baseOutPutDto.setMessage(exceptio.getMessage());
            return baseOutPutDto;
        }
    }

    /**
     * 添加动态@列表
     * @param inputDto
     * @return
     */
    public BaseOutPutDto<String> addAtList(@RequestBody BaseInputDto<List<ComAtWhoInputDto>> inputDto){

        BaseOutPutDto<String> outPutDto = new BaseOutPutDto<>();
        try{
            List<ComAtWho> atWhos = new ArrayList<>();
            for (ComAtWhoInputDto atWhoInputDto:inputDto.getData()
                 ) {
                ComAtWho atWho = new ComAtWho();
                BeanUtils.copyProperties(atWhoInputDto,atWho);
                atWhos.add(atWho);
            }
            atWhoMapper.insertList(atWhos);
            outPutDto.setStatus(Status.SUCCESS);
            return outPutDto;
        }catch (Exception exc){
            outPutDto.setStatus(Status.ERROR);
            outPutDto.setData(exc.getMessage());
            return outPutDto;
        }
    }

    /**
     * 用户删除动态
     * @param inputDto
     * @param maijiToken
     * @return
     */
    public BaseOutPutDto<String>delete(BaseInputDto<IdInputDto> inputDto,String maijiToken){

        return baseDelete(inputDto,maijiToken,1);
    }

    /**
     * 管理员删除动态
     * @param inputDto
     *
     * @return
     */
    public BaseOutPutDto<String>managerDelete(BaseInputDto<IdInputDto> inputDto){

        BaseOutPutDto<String> baseOutPutDto = new BaseOutPutDto();

        try{
            ComMsgInfo msgInfo = comMsgInfoMapper.selectById(inputDto.getData().getId());
            msgInfo.setDelete(2);

            if( comMsgInfoMapper.updateById(msgInfo) >= 1){
                baseOutPutDto.setStatus(Status.SUCCESS);
                baseOutPutDto.setData("删除成功");
            }
        }catch (Exception error){
            baseOutPutDto.setStatus(Status.ERROR);
            baseOutPutDto.setMessage(error.getMessage());
        }
        return baseOutPutDto;
    }

    private BaseOutPutDto<String>baseDelete(BaseInputDto<IdInputDto> inputDto,String maijiToken,Integer form){
        BaseOutPutDto<String> baseOutPutDto = new BaseOutPutDto();
        AppUser appUser = RedisUtil.getAppUserByRedis(redisTemplate, MyRedisConfig.REDISDATABASENO, maijiToken, userInfoService);
        String userId = appUser.getUuId();

        try{
            ComMsgInfo msgInfo = comMsgInfoMapper.selectById(inputDto.getData().getId());
            if(msgInfo.getUserId().equals(userId)){
                msgInfo.setDelete(form);

                if( comMsgInfoMapper.updateById(msgInfo) >= 1){
                    baseOutPutDto.setStatus(Status.SUCCESS);
                    baseOutPutDto.setData("删除成功");
                }
            }else{
                baseOutPutDto.setStatus(Status.ERROR);
                baseOutPutDto.setMessage("用户非发布者");
                baseOutPutDto.setData("用户非发布者");
            }

        }catch (Exception error){
            baseOutPutDto.setStatus(Status.ERROR);
            baseOutPutDto.setMessage(error.getMessage());

        }
        return baseOutPutDto;
    }

    /**
     * 动态设置为精选
     * @param inputDto
     * @return
     */
    public BaseOutPutDto<String>setEssence(BaseInputDto<IdInputDto> inputDto){

        return baseSetPriority(inputDto,2);
    }

    /**
     * 动态设置为案例
     * @param inputDto
     * @return
     */
    public BaseOutPutDto<String>setCase(BaseInputDto<IdInputDto> inputDto){

        return baseSetPriority(inputDto,3);
    }

    private BaseOutPutDto<String>baseSetPriority(BaseInputDto<IdInputDto> inputDto,Integer priority){

        BaseOutPutDto<String> baseOutPutDto = new BaseOutPutDto();

        try{
            ComMsgInfo msgInfo = comMsgInfoMapper.selectById(inputDto.getData().getId());
            msgInfo.setPriority(priority);
            if( comMsgInfoMapper.updateById(msgInfo) >= 1){
                baseOutPutDto.setStatus(Status.SUCCESS);
                baseOutPutDto.setData("设置成功");
            }
        }catch (Exception error){
            baseOutPutDto.setStatus(Status.ERROR);
            baseOutPutDto.setMessage(error.getMessage());
        }
        return baseOutPutDto;

    }

    /**
     * 管理消息置顶
     * @param inputDto
     * @return
     */
    public BaseOutPutDto<String> topListManager(BaseInputDto<ComMsgTopManInputDto>inputDto){

        BaseOutPutDto<String> baseOutPutDto = new BaseOutPutDto<>();
        try {
            ComMsgInfo msgInfo = comMsgInfoMapper.selectById(inputDto.getData().getMsgId());
            msgInfo.setTopSort(inputDto.getData().getTopSort());
            msgInfo.setIsTop(inputDto.getData().getIsTop());
            if( comMsgInfoMapper.updateById(msgInfo) >= 1){
                baseOutPutDto.setStatus(Status.SUCCESS);
                baseOutPutDto.setData("设置成功");
            }
        }catch (Exception exc){
            baseOutPutDto.setStatus(Status.ERROR);
            baseOutPutDto.setMessage(exc.getMessage());
        }
        return baseOutPutDto;
    }

    /**
     * 设置转发得积分
     * @param inputDto
     * @return
     */
    public BaseOutPutDto<String> setIntegral(BaseInputDto<IdInputDto> inputDto){
        BaseOutPutDto<String> baseOutPutDto = new BaseOutPutDto<>();
        try {
            ComMsgInfo msgInfo = comMsgInfoMapper.selectById(inputDto.getData().getId());
            msgInfo.setIsIntegral(1);
            if( comMsgInfoMapper.updateById(msgInfo) >= 1){
                baseOutPutDto.setStatus(Status.SUCCESS);
                baseOutPutDto.setData("设置成功");
            }
        }catch (Exception exc){
            baseOutPutDto.setStatus(Status.ERROR);
            baseOutPutDto.setMessage(exc.getMessage());
        }
        return baseOutPutDto;
    }

    /**
     * 取消转发积分
     * @param inputDto
     * @return
     */
    public BaseOutPutDto<String> cancelIntegral(BaseInputDto<IdInputDto> inputDto){
        BaseOutPutDto<String> baseOutPutDto = new BaseOutPutDto<>();
        try {
            ComMsgInfo msgInfo = comMsgInfoMapper.selectById(inputDto.getData().getId());
            msgInfo.setIsIntegral(0);
            if( comMsgInfoMapper.updateById(msgInfo) >= 1){
                baseOutPutDto.setStatus(Status.SUCCESS);
                baseOutPutDto.setData("取消成功");
            }
        }catch (Exception exc){
            baseOutPutDto.setStatus(Status.ERROR);
            baseOutPutDto.setMessage(exc.getMessage());
        }
        return baseOutPutDto;
    }

    /**
     * 创建at消息
     * @param msgInfo
     * @param atList
     * @param userId
     */
    private void createAtMessages(ComMsgInfo msgInfo,String[] atList,String userId){
        List<ComUserMessageInputDto> messageInputDtos = new ArrayList<>();
        for (String at:atList
             ) {
            ComUserMessageInputDto messageInputDto = new ComUserMessageInputDto();
            messageInputDto.setContent(msgInfo.getContent());
            messageInputDto.setSourceUserId(userId);
            messageInputDto.setTargetUserId(at);
            messageInputDto.setType(ComUserMessageTypeEnum.At.getValue());
            messageInputDto.setMsgId(msgInfo.getMsgId());
            messageInputDtos.add(messageInputDto);
        }
        asyncService.asycCreateMessageList(messageInputDtos);
    }

	@Override
	public BaseOutPutDto<CommunityStatisticsOutputDto> communityStatisticsQuantity(String userId) {
		logger.info("CommunityServiceImpl.communityStatisticsQuantity userId is {}",userId);
		if(StringUtils.isBlank(userId)) return new BaseOutPutDto<CommunityStatisticsOutputDto>(Status.PARAMETERERROR);
		
		EntityWrapper<ComUserRelation> comUserRelationWrapper = new EntityWrapper<ComUserRelation>();
		
		comUserRelationWrapper.eq("follower_Id", userId);
		comUserRelationWrapper.and();
		comUserRelationWrapper.eq("type", 1);
		comUserRelationWrapper.or();
		comUserRelationWrapper.eq("focuser_Id", userId);
		
		//粉丝
		List<ComUserRelation> followerSumCountList =  userRelationMapper.selectList(comUserRelationWrapper);
		//关注
		List<ComUserRelation> attentionSumCounttList =  userRelationMapper.selectList(new EntityWrapper<ComUserRelation>().eq("follower_Id", userId));
		//动态
		Integer dynamicSumCount = comMsgInfoMapper.dynamicSumCountCount(userId);
		
		CommunityStatisticsOutputDto communityStatisticsOutputDto  = new CommunityStatisticsOutputDto();
		communityStatisticsOutputDto.setAttentionSumCount(attentionSumCounttList.size());
		communityStatisticsOutputDto.setFollowerSumCount(followerSumCountList.size());
		communityStatisticsOutputDto.setDynamicSumCount(dynamicSumCount);
	
		return new BaseOutPutDto<CommunityStatisticsOutputDto>(Status.SUCCESS).setData(communityStatisticsOutputDto);
	}

	@Override
	public BaseMetaResDto<List<ComMsgInfo>> findAllComMsgInfos(Integer priority, String nickName, String content,
                                                               String act, Boolean isolation, List<Long> publishTimes, ReqMetaData metaData) {
        EntityWrapper<ComMsgInfo> entityWrapper = new EntityWrapper<>();
        if (priority == 4) entityWrapper.eq("is_integral", 1);
        if (priority == 0) {
            entityWrapper.eq("priority", 0);
            entityWrapper.eq("is_top", 0);
            entityWrapper.eq("is_integral", 0);
        }
        if (priority == 5) {
            entityWrapper.eq("is_top", 1);
            entityWrapper.orderBy("top_sort", true);
        }
        List<UserInfo> userInfos = Lists.newArrayList();
        List<String> userIds = Lists.newArrayList();
        if (StringUtil.isNotBlank(nickName)) {
            userInfos = userInfoService.selectList(nickName);
            userIds = userInfos.parallelStream().map(UserInfo::getUserId).collect(Collectors.toList());
            if (userIds.size() > 0) entityWrapper.in("user_id", userIds);
        }
        if (StringUtil.isNotBlank(content)) entityWrapper.like("content", content);
        if (StringUtil.isNotBlank(act)) entityWrapper.like("content", act);
        if (publishTimes != null && publishTimes.size() >0) {
            entityWrapper.ge("publish_time", publishTimes.get(0));
            if (publishTimes.size() > 1) entityWrapper.le("publish_time", publishTimes.get(1));
        }
        entityWrapper.eq("`delete`", 0);
        entityWrapper.eq("isolation", isolation);
        entityWrapper.orderBy("publish_time", false);
        com.baomidou.mybatisplus.plugins.Page<ComMsgInfo> page = selectPage(
                new com.baomidou.mybatisplus.plugins.Page<>(metaData.getPage(), metaData.getSize()), entityWrapper);
        List<ComMsgInfo> comMsgInfos = page.getRecords();
        if (comMsgInfos.size() > 0) {
            if (userInfos.size() == 0) userIds = page.getRecords().parallelStream().map(ComMsgInfo::getUserId).collect(Collectors.toList());
            comMsgInfos = BaseService.dealWithOneToOne(comMsgInfos,"getUserId", ComMsgInfo.class,
                    "setUser", userInfoService.selectList(userIds),"getUserId", UserInfoResData.class);
            List<String> msgIds = comMsgInfos.parallelStream().map(ComMsgInfo::getMsgId).collect(Collectors.toList());
            Map<String, List<Integer>> labelIdListMap = comMidLabelService.selectList(new EntityWrapper<ComMiddleLabel>().in("msg_id", msgIds))
                    .parallelStream().collect(Collectors.groupingBy(ComMiddleLabel::getMsgId, Collectors.mapping(ComMiddleLabel::getLabelId, Collectors.toList())));
            comMsgInfos.parallelStream().forEach(msg -> msg.setRealmName(realmName).setLabelIds(labelIdListMap.get(msg.getMsgId())));
        }
        ResMetaData resMetaData = new ResMetaData(page.getCurrent(), page.getSize(), page.getTotal());
        return new BaseMetaResDto<List<ComMsgInfo>>(Status.SUCCESS).setData(comMsgInfos).setResMetaData(resMetaData);
    }

	@Override
	public BaseMetaResDto<List<ComMsgInfo>> findAllMidComMsgInfos(Integer priority, String nickName, String content,
                                                                  String act, Boolean isolation, List<Long> publishTimes, ReqMetaData metaData) {
        EntityWrapper<ComMsgInfo> entityWrapper = new EntityWrapper<>();
        List<ComMiddleLabel> comMiddleLabels = comMidLabelService.selectList(new EntityWrapper<ComMiddleLabel>().eq("label_id", priority));
        List<String> msgIds = comMiddleLabels.parallelStream().map(ComMiddleLabel::getMsgId).collect(Collectors.toList());
        if (msgIds.size() > 0) entityWrapper.in("msg_id", msgIds);
        List<UserInfo> userInfos = Lists.newArrayList();
        List<String> userIds = Lists.newArrayList();
        if (StringUtil.isNotBlank(nickName)) {
            userInfos = userInfoService.selectList(nickName);
            userIds = userInfos.parallelStream().map(UserInfo::getUserId).collect(Collectors.toList());
            if (userIds.size() > 0) entityWrapper.in("user_id", userIds);
        }
        if (StringUtil.isNotBlank(content)) entityWrapper.like("content", content);
        if (StringUtil.isNotBlank(act)) entityWrapper.like("content", act);
        if (publishTimes != null && publishTimes.size() >0) {
            entityWrapper.ge("publish_time", publishTimes.get(0));
            if (publishTimes.size() > 1) entityWrapper.le("publish_time", publishTimes.get(1));
        }
        entityWrapper.eq("`delete`", 0);
        entityWrapper.eq("isolation", isolation);
        List<ComMsgInfo> comMsgInfos = selectList(entityWrapper);
        Long total = Long.valueOf(comMsgInfos.size());
        if (comMsgInfos.size() > 0) {
            comMsgInfos = BaseService.dealWithOneToOne(comMsgInfos,"getMsgId", ComMsgInfo.class,
                    "setLabel", comMiddleLabels,"getMsgId", ComMiddleLabel.class);
            Long startIndex = Long.valueOf(metaData.getPage() - 1) * metaData.getSize();
//            Integer endIndex = metaData.getPage() * metaData.getSize() > total -1 ? total.intValue() - 1 : metaData.getPage() * metaData.getSize();
//            comMsgInfos = comMsgInfos.parallelStream().sorted().collect(Collectors.toList()).subList(startIndex, endIndex);
            comMsgInfos = comMsgInfos.parallelStream().sorted().skip(startIndex).limit(metaData.getSize()).collect(Collectors.toList());
            msgIds = comMsgInfos.parallelStream().map(ComMsgInfo::getMsgId).collect(Collectors.toList());
            Map<String, List<Integer>> labelIdListMap = comMidLabelService.selectList(new EntityWrapper<ComMiddleLabel>().in("msg_id", msgIds))
                    .parallelStream().collect(Collectors.groupingBy(ComMiddleLabel::getMsgId, Collectors.mapping(ComMiddleLabel::getLabelId, Collectors.toList())));
            comMsgInfos.parallelStream().forEach(msg -> msg.setLabelIds(labelIdListMap.get(msg.getMsgId())));
            if (userInfos.size() == 0) userIds = comMsgInfos.parallelStream().map(ComMsgInfo::getUserId).collect(Collectors.toList());
            comMsgInfos = BaseService.dealWithOneToOne(comMsgInfos,"getUserId", ComMsgInfo.class,
                    "setUser", userInfoService.selectList(userIds),"getUserId", UserInfoResData.class);
        }
        ResMetaData resMetaData = new ResMetaData(metaData.getPage(), metaData.getSize(), total);
        return new BaseMetaResDto<List<ComMsgInfo>>(Status.SUCCESS).setData(comMsgInfos).setResMetaData(resMetaData);
    }

    @Override
    public BaseResDto editComMsgInfo (ComMsgInfo comMsgInfo) {
        String msgId = comMsgInfo.getMsgId();
        Integer priority = comMsgInfo.getPriority();
        if (priority > 10) {
            if (priority < 14) {
                Wrapper<ComMiddleLabel> wrapper = new EntityWrapper<ComMiddleLabel>()
                        .eq("label_id", priority - 10).eq("msg_id", msgId);
                if (! comMidLabelService.delete(wrapper)) return new BaseResDto(Status.ERROR);
            }
            Wrapper<ComMiddleLabel> wrapper1 = new EntityWrapper<ComMiddleLabel>().eq("msg_id", msgId);
            if (comMidLabelService.selectCount(wrapper1) == 0) comMsgInfo.setPriority(0);
        } else {
            if (Arrays.asList(1, 2, 3).contains(priority)) {
                ComMiddleLabel comMiddleLabel = new ComMiddleLabel().setLabelId(priority)
                        .setMsgId(msgId).setPublishTime(new Date().getTime());
                if (Arrays.asList(2, 3).contains(priority)) comMiddleLabel.setIsShow(1);
                if (! comMidLabelService.insert(comMiddleLabel)) return new BaseResDto(Status.ERROR);
            }
        }
        if (BooleanUtils.isTrue(comMsgInfo.getIsolation())) comMsgInfo.setExamined(2);
        if (updateById(comMsgInfo)) return new BaseResDto(Status.SUCCESS);
        return new BaseResDto(Status.ERROR);
    }

    @Override
    public BaseDataResDto<ComMsgBaseOutputDto> findComMsgById(String msgId) {
        ComMsgInfo comMsgInfo = selectById(msgId);
        if (comMsgInfo == null) return new BaseDataResDto<>(Status.ERROR);
        ComMsgBaseOutputDto dto = new ComMsgBaseOutputDto();
        BeanUtils.copyProperties(comMsgInfo, dto);
        UserInfoResData user = userInfoService.findUserInfoResDataByUserId(comMsgInfo.getUserId());
        HashMap<String, Object> imgMap = Maps.newHashMap();
        imgMap.put("belongIds", Arrays.asList(comMsgInfo.getMsgId()));
        List<UploadImageResData> imgs = uploadRecordService.findResDataList(imgMap);
        dto.setUser(user).setFiles(imgs);
        return new BaseDataResDto<ComMsgBaseOutputDto>(Status.SUCCESS).setData(dto);
    }

    /**
     * 根据活动搜索动态列表 ， 置顶独立
     * @param inputDto
     * @param maijiToken
     * @return
     */
    public BaseOutPutDto<List<ComRecsOutputDto>> findMsgsByActName(BaseInputDto<ComRecsInputDto> inputDto,String maijiToken){

        String userId = "";
        if(!StringUtil.isBlank(maijiToken)){
            AppUser appUser = RedisUtil.getAppUserByRedis(redisTemplate, MyRedisConfig.REDISDATABASENO, maijiToken, userInfoService);
            if(appUser != null){
                userId = appUser.getUuId();
            }
        }

        ComRecsInputDto recsInputDto = inputDto.getData();
//
//        ArrayList<ComMiddleActivity> allCommiddleActList = new ArrayList();
//
//        ComMiddleActivity topComMiddleActivityQ = new ComMiddleActivity();
//        topComMiddleActivityQ.setActName(recsInputDto.getActName());
//        topComMiddleActivityQ.setIsTop(1);
//        EntityWrapper<ComMiddleActivity> topentityWrapper = new EntityWrapper(topComMiddleActivityQ);
//        topentityWrapper.orderBy("top_sort",true);
//
//        List<ComMiddleActivity> topComMiddleActivityList = comMidActMapper.selectList(topentityWrapper);
//        if(topComMiddleActivityList != null && topComMiddleActivityList.size() > 0){
//            allCommiddleActList.addAll(topComMiddleActivityList);
//        }
//
//
//        ComMiddleActivity comMiddleActivityQ = new ComMiddleActivity();
//        comMiddleActivityQ.setActName(recsInputDto.getActName());
//        comMiddleActivityQ.setIsTop(0);
//        EntityWrapper<ComMiddleActivity> entityWrapper = new EntityWrapper(comMiddleActivityQ);
//        entityWrapper.orderBy("publish_time",
//                false);
//        if(recsInputDto.getPublishTime() != null && recsInputDto.getPublishTime() != 0){
//            entityWrapper.where(MessageFormat.format("{0} > publish_time",recsInputDto.getPublishTime().toString()));
//        }
//        List<ComMiddleActivity> comMiddleActivityList = comMidActMapper.selectPage(new com.baomidou.mybatisplus.plugins.Page<>(inputDto.getMetaData().getPage(), inputDto.getMetaData().getSize()),entityWrapper);
//        if(comMiddleActivityList != null && comMiddleActivityList.size() > 0){
//            allCommiddleActList.addAll(comMiddleActivityList);
//        }
//        List<String> msgIds = allCommiddleActList.parallelStream().map(ComMiddleActivity::getMsgId).collect(Collectors.toList());
//
//        List<ComMsgInfo> comMsgInfos = new ArrayList<>();
//        if(msgIds.size()>0){
//            comMsgInfos = comMsgInfoMapper.findListByMsgIds(msgIds,userId);
//        }

        List<ComMsgInfo> comMsgInfos = comMsgInfoMapper.findMsgsByActName(userId,recsInputDto.getPublishTime(),0 ,inputDto.getMetaData().getSize(),0,false,recsInputDto.getActName());
        for (ComMsgInfo comMsgInfo : comMsgInfos){
            if(comMsgInfo.getActs() != null){
                for (ComMiddleActivity act : comMsgInfo.getActs()){
                    if(act.getActName().equals(recsInputDto.getActName())){
                        comMsgInfo.setIsTop(act.getIsTop());
                        comMsgInfo.setTopSort(act.getTopSort());
                    }
                }
            }
        }
        BaseOutPutDto<List<ComRecsOutputDto>> baseOutPutDto = reloadMsgInfos(comMsgInfos,userId);
//        for (ComRecsOutputDto comOutPutDto:baseOutPutDto.getData()
//             ) {
//            for (ComMiddleActivity activity : allCommiddleActList
//                 ) {
//                if (activity.getMsgId().equals(comOutPutDto.getMsg().getMsgId())){
//                    comOutPutDto.getMsg().setTopSort(activity.getTopSort());
//                    comOutPutDto.getMsg().setIsTop(activity.getIsTop());
//                }
//            }
//        }

        return baseOutPutDto;

    }

    /**
     * 首页列表
     * @param inputDto
     * @param maijiToken
     * @return
     */
    public BaseOutPutDto<List<ComRecsOutputDto>> homePageList(BaseInputDto<ComRecsInputDto> inputDto,String maijiToken){

        String userId = "";
        if(!StringUtil.isBlank(maijiToken)){
            AppUser appUser = RedisUtil.getAppUserByRedis(redisTemplate, MyRedisConfig.REDISDATABASENO, maijiToken, userInfoService);
            if(appUser != null){
                userId = appUser.getUuId();
            }
        }


        return findMsgInfosByLabelId(inputDto,ComLabelEnum.ComLabelEnum_HP.getValue(),userId);
    }

    @Override
    public BaseOutPutDto<ComMsgTransmitRule> findMsgTransmitRule () {
        Query query = new Query();
        ComMsgTransmitRule comMsgTransmitRule = mongoTemplate.findOne(query, ComMsgTransmitRule.class, ComMsgTransmitRule.TABLE_NAME);
        return new BaseOutPutDto<ComMsgTransmitRule>(Status.SUCCESS).setData(comMsgTransmitRule);
    }

    @Override
    public BaseOutPutDto updMsgTransmitRule (BaseInputDto<ComMsgTransmitRule> inputDto ) {
        Query query = new Query();
        mongoTemplate.findAndRemove(query, ComMsgTransmitRule.class, ComMsgTransmitRule.TABLE_NAME);
        mongoTemplate.save(inputDto.getData(), ComMsgTransmitRule.TABLE_NAME);
        return new BaseOutPutDto(Status.SUCCESS);
    }

    private Boolean checkUserTraIntNum(String userId , Integer maxTransmitNum){

        try{
            EntityWrapper<ComMsgTransmit> entityWrapper = new EntityWrapper<>();
            entityWrapper.setEntity(new ComMsgTransmit()
                    .setSourceUserId(userId)
                    .setIsIntegral(1));
            Long startTime = TimeUtil.getZeroTime(new Date()).getTime();
            Long endTime = TimeUtil.getCurDateStamp();
            entityWrapper.where(MessageFormat.format("transmit_time >= {0} and {1} >= transmit_time",startTime.toString() ,endTime.toString()));
            List<ComMsgTransmit> msgTransmits = msgTransmitMapper.selectList(entityWrapper);

            if(msgTransmits.size()<maxTransmitNum){
                return true;
            }

            return false;
        }catch (Exception exc){
            return false;
        }
    }

    private Boolean checkTraIntRestartDay(String belongId , String userId , Integer restartDay){

        try{

            EntityWrapper<ComMsgTransmit> entityWrapper = new EntityWrapper<>();
            entityWrapper.setEntity(new ComMsgTransmit().setBelongId(belongId)
                    .setSourceUserId(userId)
                    .setIsIntegral(1));
            entityWrapper.orderBy("transmit_time",false);
            List<ComMsgTransmit> msgTransmits = msgTransmitMapper.selectList(entityWrapper);
            if(msgTransmits.size() > 0){

                ComMsgTransmit msgTransmit = msgTransmits.get(0);
                int space = TimeUtil.daysBetween(new Date(msgTransmit.getTransmitTime()), new Date());
                if(space > restartDay){
                    return true;
                }else{
                    return false;
                }
            }else{
                return true;
            }

        }catch (Exception exc){
            return false;
        }

    }

    @Override
    public BaseDataResDto<ComMsgTransmitRule> findComMsgTransmitRule () {
        ComMsgTransmitRule comMsgTransmitRule = mongoTemplate.findOne(new Query(), ComMsgTransmitRule.class, ComMsgTransmitRule.TABLE_NAME);
        return new BaseDataResDto<ComMsgTransmitRule>(Status.SUCCESS).setData(comMsgTransmitRule);
    }

    @Override
    public BaseResDto editComMsgTransmitRule(ComMsgTransmitRule rule) {
        mongoTemplate.remove(new Query(), ComMsgTransmitRule.TABLE_NAME);
        mongoTemplate.save(rule, ComMsgTransmitRule.TABLE_NAME);
        mongoTemplate.save(rule, ComMsgTransmitRule.TABLE_LOG_NAME);
        return new BaseResDto(Status.SUCCESS);
    }

    @Override
    public BaseDataResDto<List<ComMsgTransmitRule>> findAllComMsgTransmitRuleLogs(List<Date> editDates) {
        Query query = new Query().skip(1).with(new Sort(new Sort.Order(Sort.Direction.DESC,"updateDate")));
        if (editDates != null) {
            Date startDate = editDates.size() > 0 ? editDates.get(0): null;
            Criteria updateDateCriteria = Criteria.where("updateDate");
            Boolean updFlag = false;
            if (startDate != null) {
                updateDateCriteria = updateDateCriteria.gte(startDate);
                updFlag = true;
            }
            Date endDate = editDates.size() > 1 ? editDates.get(1): null;
            if (endDate != null) {
                updateDateCriteria = updateDateCriteria.lte(endDate);
                updFlag = true;
            }
            if (updFlag) query.addCriteria(updateDateCriteria);
        }
        List<ComMsgTransmitRule> ruleLogList = mongoTemplate.find(query, ComMsgTransmitRule.class, ComMsgTransmitRule.TABLE_LOG_NAME);
        return new BaseDataResDto<List<ComMsgTransmitRule>>(Status.SUCCESS).setData(ruleLogList);
    }


    private BaseOutPutDto<List<ComRecsOutputDto>> findMsgInfosByLabelId(BaseInputDto<ComRecsInputDto> inputDto , int labelId , String userId) {

        ComRecsInputDto recsInputDto = inputDto.getData();

        ArrayList<ComMiddleLabel> allCommiddleLabelList = new ArrayList();

        List<ComMsgInfo> comMsgInfos = new ArrayList<>();

        List<String> msgIds = new ArrayList<>();

        if (inputDto.getData().getPublishTime() == null || inputDto.getData().getPublishTime() == 0) {
            ComMsgInfo msgInfoQ = new ComMsgInfo();
            msgInfoQ.setIsTop(1);
            EntityWrapper<ComMsgInfo> entityWrapper = new EntityWrapper<>(msgInfoQ);
            entityWrapper.orderBy("top_sort",true);
            msgIds.addAll(comMsgInfoMapper.selectList(entityWrapper).parallelStream().map(ComMsgInfo::getMsgId).collect(Collectors.toList()));
        }

        if (inputDto.getData().getPublishTime() == null || inputDto.getData().getPublishTime() == 0) {
            ComMiddleLabel topComMiddleActivityQ = new ComMiddleLabel();
            topComMiddleActivityQ.setLabelId(labelId);
            topComMiddleActivityQ.setIsTop(1);
            EntityWrapper<ComMiddleLabel> topentityWrapper = new EntityWrapper(topComMiddleActivityQ);
            topentityWrapper.orderBy("top_sort", true);

            List<ComMiddleLabel> topComMiddleLabelList = comMidLabelService.selectList(topentityWrapper);
            if (topComMiddleLabelList != null && topComMiddleLabelList.size() > 0) {
                allCommiddleLabelList.addAll(topComMiddleLabelList);
            }
        }

        ComMiddleLabel comMiddleLabelQ = new ComMiddleLabel();
        comMiddleLabelQ.setLabelId(labelId);
        comMiddleLabelQ.setIsTop(0);
        EntityWrapper<ComMiddleLabel> entityWrapper = new EntityWrapper(comMiddleLabelQ);
        entityWrapper.orderBy("publish_time",
                false);
        if (recsInputDto.getPublishTime() != null && recsInputDto.getPublishTime() != 0) {
            entityWrapper.where(MessageFormat.format("{0} > publish_time", recsInputDto.getPublishTime().toString()));
        }
        com.baomidou.mybatisplus.plugins.Page page = new com.baomidou.mybatisplus.plugins.Page<ComMiddleLabel>(0, inputDto.getMetaData().getSize());
        List<ComMiddleLabel> comMiddleLabelList = comMidLabelService.selectPage(page, entityWrapper).getRecords();

        if (comMiddleLabelList != null && comMiddleLabelList.size() > 0) {
            allCommiddleLabelList.addAll(comMiddleLabelList);
        }
        msgIds.addAll(allCommiddleLabelList.parallelStream().map(ComMiddleLabel::getMsgId).collect(Collectors.toList()));


        if (msgIds.size() > 0) {
            comMsgInfos.addAll(comMsgInfoMapper.findListByMsgIds(msgIds, userId));
        }

        BaseOutPutDto<List<ComRecsOutputDto>> baseOutPutDto = reloadMsgInfos(comMsgInfos, userId);
        for (ComRecsOutputDto comOutPutDto : baseOutPutDto.getData()
        ) {
            for (ComMiddleLabel middleLabel : allCommiddleLabelList
            ) {
                if (middleLabel.getMsgId().equals(comOutPutDto.getMsg().getMsgId())) {
                    if (comOutPutDto.getMsg().getTopSort() == null)
                        comOutPutDto.getMsg().setTopSort(middleLabel.getTopSort());
                    if (comOutPutDto.getMsg().getIsTop() == null)
                        comOutPutDto.getMsg().setIsTop(middleLabel.getIsTop());
                }
            }
        }
        return baseOutPutDto;
    }
}
